package com.example.questionnaire.mbg.controller;

import com.example.questionnaire.exception.NotFindException;
import com.example.questionnaire.mbg.comman.R;
import com.example.questionnaire.mbg.entity.*;
import com.example.questionnaire.mbg.entity.Enum.QuestionTypeEnum;
import com.example.questionnaire.mbg.entity.Enum.QuestionnaireStatusEnum;
import com.example.questionnaire.mbg.service.impl.*;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

@RestController
@RequestMapping("/result")
public class ResultController {
    @Resource
    private QuestionnaireServiceImpl questionnaireService;

    @Resource
    private QuestionServiceImpl questionService;

    @Resource
    private OptionServiceImpl optionService;

    @Resource
    private ResultServiceImpl resultService;

    @Resource
    private AnswerServiceImpl answerService;

    @PostMapping("/fill")
    public R fill(@RequestParam Integer qnid,Integer uid, @RequestBody ArrayList<Object> results) {
        Questionnaire questionnaire = questionnaireService.get(qnid);
        if (null == questionnaire) {
            throw new NotFindException("qnid");
        }

        if (QuestionnaireStatusEnum.PUBLISHED != questionnaire.getStatus()) {
            return R.fail("问卷不在发布状态");
        }

        if (questionnaire.getInTrash()) {
            return R.fail("问卷已删除");
        }
        if(uid != 0){
            Answer answer = answerService.getAnByQnidandUid(qnid, uid);
            if(answer != null)
                return R.fail("该用户已填写");
        }
        Answer answer = Answer.builder().userId(uid)
                .questionnaireId(qnid)
                .writeTime(new Date()).build();
        int answerId = answerService.insertAnswer(answer);
        System.out.println(answerId);
        questionnaireService.incReceiveCnt(qnid);
        for (int idx = 0; idx < results.size(); idx++) {
            if (results.get(idx) == null) continue;
            Question question = questionService.getByQuestionNumber(qnid, idx);
            if (null == question) {
                throw new NotFindException("questionNumber");
            }

            questionService.incReceiveCnt(question.getId());

            Result result = Result.builder().questionId(question.getId()).answerId(answerId).build();

            switch (question.getQuestionType()) {
                case CHECKBOX:
                    List<Integer> choices = (List<Integer>) (results.get(idx));
                    for (Integer choice : choices) {
                        result.setChoice(choice);
                        resultService.insertResult(result);
                    }
                    break;
                case RATING:
                case RADIO:
                    result.setChoice((Integer) (results.get(idx)));
                    resultService.insertResult(result);
                    break;
                case INPUT:
                    result.setContent((String) (results.get(idx)));
                    resultService.insertResult(result);
                    break;
            }
        }
        return R.success();
    }

    @GetMapping("/analyze")
    public R analyze(@RequestParam Integer qnid) {
        Questionnaire questionnaire = questionnaireService.get(qnid);
        if (null == questionnaire) {
            throw new NotFindException("qnid");
        }

        HashMap<String, Object> hmp = new HashMap<>();
        List<Answer> fills = answerService.getAnByQnid(qnid);
        if(fills.size() == 0)
            hmp.put("message","none");
        else
            hmp.put("message","notNone");
        hmp.put("headline", questionnaire.getTitle());
        hmp.put("description", questionnaire.getDescription());
        List<HashMap<String, Object>> list = new ArrayList<>();
        List<Question> questions = questionService.listAll(qnid);
        for (int i = 0; i < questions.size(); i++) {
            HashMap<String, Object> submp = new HashMap<>();
            submp.put("id", questions.get(i).getId());
            submp.put("total", questions.get(i).getReceiveCnt());
            submp.put("title", questions.get(i).getContent());
            submp.put("type", questions.get(i).getQuestionType());
            submp.put("noneable", questions.get(i).getNullable());
            List<HashMap<String, Object>> statistics = new ArrayList<>();
            switch (questions.get(i).getQuestionType()) {
                case CHECKBOX:
                case RADIO:
                case RATING:
                    List<Option> options = optionService.listAll(questions.get(i).getId());
                    for (int j = 0; j < options.size(); j++) {
                        int cnt = resultService.getCntByQidAndOid(questions.get(i).getId(), options.get(j).getOptionNumber());
                        HashMap<String, Object> subsubmp = new HashMap<>();
                        subsubmp.put("option", options.get(j).getContent());
                        subsubmp.put("numPerOption", cnt);
                        subsubmp.put("right",options.get(j).getIsRight());
                        statistics.add(subsubmp);
                    }
                    break;
                case INPUT:
                    List<Result> results = resultService.getReByQidAndOid(questions.get(i).getId(), 0);
                    for (int j = 0; j < results.size(); j++) {
                        HashMap<String, Object> subsubmp = new HashMap<>();
                        subsubmp.put("index", j + 1);
                        subsubmp.put("answer", results.get(j).getContent());
                        statistics.add(subsubmp);
                    }
                    break;
            }
            submp.put("statistic", statistics);
            list.add(submp);
        }
        hmp.put("questionnaire", list);
        return R.success(hmp);
    }

    @GetMapping("/analyzeAll")
    public R analyze1(@RequestParam Integer qnid) {
        Questionnaire questionnaire = questionnaireService.get(qnid);
        if (null == questionnaire) {
            throw new NotFindException("qnid");
        }

        HashMap<String, Object> hmp = new HashMap<>();
        hmp.put("headline", questionnaire.getTitle());
        hmp.put("description", questionnaire.getDescription());
        hmp.put("type", questionnaire.getQuestionnaireType());
        List<HashMap<String, Object>> list = new ArrayList<>();
        List<HashMap<String, Object>> list1 = new ArrayList<>();
        List<Question> questions = questionService.listAll(qnid);
        List<Answer> fills = answerService.getAnByQnid(qnid);
        if(fills.size() == 0){
            HashMap<String,Object> map = new HashMap<>();
            map.put("message", "none");
            return R.success(map);
        }
        else {
            hmp.put("total", fills.size());
            hmp.put("message", "notNone");
            for (int i = 0; i < questions.size(); i++) {
                HashMap<String, Object> submp = new HashMap<>();
                submp.put("title", questions.get(i).getContent());
                QuestionTypeEnum questionType = questions.get(i).getQuestionType();
                submp.put("type", questionType);
                submp.put("nullable", questions.get(i).getNullable());
                submp.put("grade", questions.get(i).getScore());
                switch (questionType) {
                    case RADIO:
                        List<Option> option = optionService.getAnswer(questions.get(i).getId());
                        if(option.size() == 0)
                            submp.put("rightAnswer", "none");
                        else
                            submp.put("rightAnswer", option.get(0).getContent());
                        break;
                    case CHECKBOX:
                        List<Option> options = optionService.getAnswer(questions.get(i).getId());
                        if(options.size() == 0)
                            submp.put("rightAnswer", "none");
                        else {
                            List<String> answers = new ArrayList<>();
                            for (int j = 0; j < options.size(); j++) {
                                answers.add(options.get(j).getContent());
                            }
                            String an = StringUtils.join(answers,",");
                            submp.put("rightAnswer", an);
                        }
                        break;
                    case INPUT:
                    case RATING:
                        submp.put("rightAnswer", "none");
                        break;
                }
                list.add(submp);
            }
            for (int i = 0; i < fills.size(); i++) {
                HashMap<String, Object> remap = new HashMap<>();
                List<HashMap<String, Object>> list2 = new ArrayList<>();
                int aid = fills.get(i).getId();
                int grade = 0, num = 0;
                remap.put("date", fills.get(i).getWriteTime());
                remap.put("index", i + 1);
                for (int j = 0; j < questions.size(); j++) {
                    HashMap<String, Object> momap = new HashMap<>();
                    List<Result> results = resultService.getReByAidAndQid(aid, questions.get(j).getId());
                    switch (questions.get(j).getQuestionType()) {
                        case RADIO:
                            List<Option> answer = optionService.getAnswer(questions.get(j).getId());
                            Option option = optionService.getByQidAndOnum(questions.get(j).getId(), results.get(0).getChoice());
                            if (option.getIsRight().equals(true)) {
                                num++;
                                grade = grade + questions.get(j).getScore();
                            }
                            momap.put("a", option.getContent());
                            break;
                        case CHECKBOX:
                            List<String> str = new ArrayList<>();
                            List<Option> answers = optionService.getAnswer(questions.get(j).getId());
                            int[] in2 = new int[100];
                            for (int p = 0; p < results.size(); p++) {
                                Option option1 = optionService.getByQidAndOnum(questions.get(j).getId(), results.get(p).getChoice());
                                in2[p] = results.get(p).getChoice();
                                str.add(option1.getContent());
                            }
                            String ans = StringUtils.join(str,",");
                            momap.put("a", ans);
                            if(answers.size() != 0) {
                                int[] in1 = new int[100];
                                for (int m = 0; m < answers.size(); m++) {
                                    in1[m] = answers.get(m).getOptionNumber();
                                }
                                Arrays.sort(in1);
                                Arrays.sort(in2);
                                if (Arrays.equals(in1, in2)) {
                                    num++;
                                    grade = grade + questions.get(j).getScore();
                                }
                            }
                            break;
                        case RATING:
                            Option option2 = optionService.getByQidAndOnum(questions.get(j).getId(), results.get(0).getChoice());
                            momap.put("a", option2.getContent());
                            break;
                        case INPUT:
                            momap.put("a", results.get(0).getContent());
                            break;
                    }
                    list2.add(momap);
                }
                remap.put("answer", list2);
                remap.put("grade", grade);
                remap.put("num", num);
                list1.add(remap);
            }
            hmp.put("questions", list);
            hmp.put("answers", list1);
            return R.success(hmp);
        }
    }

    @GetMapping("/analyzeUser")
    public R analyze2(@RequestParam Integer qnid, Integer uid) {
        Questionnaire questionnaire = questionnaireService.get(qnid);
        if (null == questionnaire) {
            throw new NotFindException("qnid");
        }

        HashMap<String, Object> hmp = new HashMap<>();
        hmp.put("headline", questionnaire.getTitle());
        hmp.put("description", questionnaire.getDescription());
        hmp.put("type",questionnaire.getQuestionnaireType());
        List<HashMap<String, Object>> list = new ArrayList<>();
        List<HashMap<String, Object>> list1 = new ArrayList<>();
        List<Question> questions = questionService.listAll(qnid);
        Answer fill = answerService.getAnByQnidandUid(qnid, uid);
        for (int i = 0; i < questions.size(); i++) {
            HashMap<String, Object> submp = new HashMap<>();
            submp.put("title", questions.get(i).getContent());
            QuestionTypeEnum questionType = questions.get(i).getQuestionType();
            submp.put("type", questionType);
            submp.put("nullable", questions.get(i).getNullable());
            submp.put("grade", questions.get(i).getScore());
            switch (questionType){
                case RADIO:
                    List<Option> option = optionService.getAnswer(questions.get(i).getId());
                    if(option.size() == 0)
                        submp.put("rightAnswer", "none");
                    else
                        submp.put("rightAnswer", option.get(0).getContent());
                    break;
                case CHECKBOX:
                    List<Option> options = optionService.getAnswer(questions.get(i).getId());
                    if(options.size() == 0)
                        submp.put("rightAnswer", "none");
                    else {
                        List<String> answers = new ArrayList<>();
                        for (int j = 0; j < options.size(); j++) {
                            answers.add(options.get(j).getContent());
                        }
                        String an = StringUtils.join(answers,",");
                        submp.put("rightAnswer", an);
                    }
                    break;
                case INPUT:
                case RATING:
                    submp.put("rightAnswer", "none");
                    break;
            }
            list.add(submp);
        }

        HashMap<String,Object> remap = new HashMap<>();
        List<HashMap<String,Object>> list2 = new ArrayList<>();
        int aid = fill.getId();
        int grade = 0, num = 0;
        remap.put("date",fill.getWriteTime());
        for(int j=0;j<questions.size();j++){
            HashMap<String,Object> momap = new HashMap<>();
            List<Result> results = resultService.getReByAidAndQid(aid,questions.get(j).getId());
            switch (questions.get(j).getQuestionType()) {
                case RADIO:
                    List<Option> answer = optionService.getAnswer(questions.get(j).getId());
                    Option option = optionService.getByQidAndOnum(questions.get(j).getId(),results.get(0).getChoice());
                    if(option.getIsRight().equals(true)){
                        num++;
                        grade = grade + questions.get(j).getScore();
                    }
                    momap.put("a", option.getContent());
                    break;
                case CHECKBOX:
                    List<String> str = new ArrayList<>();
                    List<Option> answers = optionService.getAnswer(questions.get(j).getId());
                    int[] in2 = new int[100];
                    for(int p=0;p<results.size();p++){
                        Option option1 = optionService.getByQidAndOnum(questions.get(j).getId(),results.get(p).getChoice());
                        in2[p] = results.get(p).getChoice();
                        str.add(option1.getContent());
                    }
                    String ans = StringUtils.join(str,",");
                    momap.put("a",ans);
                    if(answers.size() != 0) {
                        int[] in1 = new int[100];
                        for (int m = 0; m < answers.size(); m++) {
                            in1[m] = answers.get(m).getOptionNumber();
                        }
                        Arrays.sort(in1);
                        Arrays.sort(in2);
                        if (Arrays.equals(in1, in2)) {
                            num++;
                            grade = grade + questions.get(j).getScore();
                        }
                    }
                    break;
                case RATING:
                    Option option2 = optionService.getByQidAndOnum(questions.get(j).getId(),results.get(0).getChoice());
                    momap.put("a", option2.getContent());
                    break;
                case INPUT:
                    momap.put("a",results.get(0).getContent());
                    break;
            }
            list2.add(momap);
        }
        remap.put("answer",list2);
        remap.put("grade",grade);
        remap.put("num",num);
        list1.add(remap);

        hmp.put("questions", list);
        hmp.put("answers",list1);
        return R.success(hmp);
    }

}
